package org.jrfe.net.simple;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import org.jrfe.net.NetPackege;
import org.jrfe.net.SyncQueue;

public class SClient implements Runnable{

	protected int port;
	protected String ip;

	protected NetworkCallback callback;

	protected boolean running;
	protected Thread thread;

	protected Socket socket;

	protected ObjectInputStream ois;
	protected ObjectOutputStream oos;

	protected SyncQueue<NetPackege> queue;
	
	public boolean ready;
	
	public SClient(String ip,int port,NetworkCallback callback) {
		this.ip = ip;
		this.port = port;
		this.callback = callback;
		queue = new SyncQueue<NetPackege>();
		ready = false;
	}
	
	public void start(){
		thread = new Thread(this);
		running = true;
		thread.start();
	}
	
	public void stop(){
		running = false;
		try {
			oos.close();
			ois.close();
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void connect(){
		try {
			System.out.println("Connection to server...");
			socket = new Socket(ip,port);
			oos = new ObjectOutputStream(socket.getOutputStream());
			ois = new ObjectInputStream(socket.getInputStream());
			ready = true;
			callback.connected();
			System.out.println("Connected to server");
		} catch (UnknownHostException e) {
			callback.connectionError();
			System.out.println("Host not found");
		} catch (IOException e) {
			callback.connectionError();
			System.out.println("Not Connected!!!");
		}
	}
	
	public synchronized boolean send(NetPackege pkg){
		if(ready){
			try {
				oos.writeObject(pkg);
				oos.flush();
			} catch (Exception e) {
				callback.connectionError();
				// callback sending error (connection was lost or something like that)
				e.printStackTrace();
			}
			
			return true;
		}
		
		return false;
		
	}
	
	@Override
	public void run() {
		while(running){
			if(!ready){
				connect();
			}else{
				try {
					Object ob = ois.readObject();
					if(ob != null){
						queue.writeQueue((NetPackege) ob);
					}
				} catch (Exception e){
					System.out.println("Connection lost!!!");
					callback.connectionLost();
					ready = false;
				}
			}
			
		}
		
	}
	
	public Thread getThread() {
		return thread;
	}
	
	public SyncQueue<NetPackege> getQueue() {
		return queue;
	}
}
